<?php
/**
 * Created by PhpStorm.
 * User: yf
 * Date: 2018/5/28
 * Time: 下午6:33
 */

namespace EasySwoole\EasySwoole;

use App\CronTask\BetCron;
use App\CronTask\CheckMatchStatusCron;
use App\CronTask\CompositeStatsCron;
use App\CronTask\CsgoBattleCron;
use App\CronTask\HeroesCron;
use App\CronTask\KogBattleCron;
use App\CronTask\LeagueCron;

use App\CronTask\LeagueScoreCron;
use App\CronTask\LiveBattleCron;
use App\CronTask\LiveVideoCron;
use App\CronTask\MatchListsCron;
use App\CronTask\PlayersCron;
use App\CronTask\RawItemsCron;
use App\CronTask\RecentlyMatchCron;
use App\CronTask\RunesCron;
use App\CronTask\SkillsCron;
use App\CronTask\SpecialCron;
use App\CronTask\TeamCron;
use App\CronTask\TeamPointsCron;
use App\Enums\UrlEnums;
use App\Process\CheckMatchStatus;
use App\Process\CsgoBet;
use App\Process\DotaBet;
use App\Process\KogBet;
use App\Process\LeagueScore;
use App\Process\LolBet;
use App\WebSocket\WebSocketEvent;
use App\WebSocket\WebSocketParser;
use EasySwoole\EasySwoole\Crontab\Crontab;
use EasySwoole\EasySwoole\Swoole\EventRegister;
use EasySwoole\EasySwoole\AbstractInterface\Event;
use EasySwoole\FastCache\Cache;
use EasySwoole\Http\Message\Status;
use EasySwoole\Http\Request;
use EasySwoole\Http\Response;
use EasySwoole\MysqliPool\MysqlPoolException;
use EasySwoole\RedisPool\Redis;
use EasySwoole\Socket\Dispatcher;


class EasySwooleEvent implements Event
{

    public static function initialize()
    {
        // TODO: Implement initialize() method.
        date_default_timezone_set('Asia/Shanghai');
        $redisConfig = new \EasySwoole\RedisPool\Config(Config::getInstance()->getConf('REDIS'));
        $redis = Redis::getInstance()->register('redis',$redisConfig);
        $redis->setMaxObjectNum(100);
        $mysqlConfig = new \EasySwoole\Mysqli\Config(Config::getInstance()->getConf('MYSQL'));
        try {
            \EasySwoole\MysqliPool\Mysql::getInstance()->register('mysql', $mysqlConfig);
        } catch (MysqlPoolException $e) {
            echo "[Warn] --> mysql池注册失败\n";
        }
    }

    public static function mainServerCreate(EventRegister $register)
    {
        /**
         * 定时器
         */
        Crontab::getInstance()->addTask(HeroesCron::class);//更新英雄
        Crontab::getInstance()->addTask(LeagueCron::class);//更新联赛
        Crontab::getInstance()->addTask(LeagueScoreCron::class);
        Crontab::getInstance()->addTask(MatchListsCron::class);//更新已结束比赛
        Crontab::getInstance()->addTask(LiveVideoCron::class);//更新直播地址源
        Crontab::getInstance()->addTask(TeamCron::class);//更新战队
        Crontab::getInstance()->addTask(PlayersCron::class);//更新选手信息
        Crontab::getInstance()->addTask(RawItemsCron::class);//更新装备信息
        Crontab::getInstance()->addTask(SkillsCron::class);//更新召唤师技能
        Crontab::getInstance()->addTask(RunesCron::class);//更新符文数据
        //Crontab::getInstance()->addTask(CheckMatchStatusCron::class);
        Crontab::getInstance()->addTask(LiveBattleCron::class);//更新战役详情
        Crontab::getInstance()->addTask(RecentlyMatchCron::class);//更新近期赛事列表
        Crontab::getInstance()->addTask(CsgoBattleCron::class);//单独更新csgo战役详情
        Crontab::getInstance()->addTask(BetCron::class);//更新赔率详情
        Crontab::getInstance()->addTask(KogBattleCron::class);
        $maxDepth = 3;

        $league = new LeagueScore('maxDepth',['maxDepth'=>$maxDepth,'table'=>'siam_lolscore',false.\EasySwoole\Component\Process\Config::PIPE_TYPE_SOCK_DGRAM,true]);
        ServerManager::getInstance()->getSwooleServer()->addProcess($league->getProcess());
        //更新正在进行的赔率
        $lolbet = new LolBet('maxDepth',['maxDepth'=>$maxDepth,'maxCoroutineNum'=>1,false,\EasySwoole\Component\Process\Config::PIPE_TYPE_SOCK_DGRAM,true]);
        ServerManager::getInstance()->getSwooleServer()->addProcess($lolbet->getProcess());
        $dotabet = new DotaBet('maxDepth',['maxDepth'=>$maxDepth,'maxCoroutineNum'=>1,false,\EasySwoole\Component\Process\Config::PIPE_TYPE_SOCK_DGRAM,true]);
        ServerManager::getInstance()->getSwooleServer()->addProcess($dotabet->getProcess());
        $csgobet = new CsgoBet('',['maxDepth'=>$maxDepth,'maxCoroutineNum'=>1,false,\EasySwoole\Component\Process\Config::PIPE_TYPE_SOCK_DGRAM,true]);
        ServerManager::getInstance()->getSwooleServer()->addProcess($csgobet->getProcess());
        $kogbet = new KogBet('',['maxDepth'=>$maxDepth,'maxCoroutineNum'=>1,false,\EasySwoole\Component\Process\Config::PIPE_TYPE_SOCK_DGRAM,true]);
        ServerManager::getInstance()->getSwooleServer()->addProcess($kogbet->getProcess());

        //更新比赛状态
        $csgoMatchStatus = new CheckMatchStatus('',['table'=>'siam_csgomatchs','path'=>UrlEnums::CSGO_LIVE_MATCH_PATH,false,\EasySwoole\Component\Process\Config::PIPE_TYPE_SOCK_DGRAM,true]);
        ServerManager::getInstance()->getSwooleServer()->addProcess($csgoMatchStatus->getProcess());
        $lolMatchStatus = new CheckMatchStatus('',['table'=>'siam_lolmatchs','path'=>UrlEnums::LOL_LIVE_MATCH_PATH,false,\EasySwoole\Component\Process\Config::PIPE_TYPE_SOCK_DGRAM,true]);
        ServerManager::getInstance()->getSwooleServer()->addProcess($lolMatchStatus->getProcess());
        $dotaMatchStatus = new CheckMatchStatus('',['table'=>'siam_dotamatchs','path'=>UrlEnums::DOTA_LIVE_MATCH_PATH,false,\EasySwoole\Component\Process\Config::PIPE_TYPE_SOCK_DGRAM,true]);
        ServerManager::getInstance()->getSwooleServer()->addProcess($dotaMatchStatus->getProcess());
        $kogMatchStatus = new CheckMatchStatus('',['table'=>'siam_kogmatchs','path'=>UrlEnums::KOG_LIVE_MATCH_PATH,false,\EasySwoole\Component\Process\Config::PIPE_TYPE_SOCK_DGRAM,true]);
        ServerManager::getInstance()->getSwooleServer()->addProcess($kogMatchStatus->getProcess());

        /**
         * **************** websocket控制器 **********************
         */
        //创建dispatcher配置
        $conf = new \EasySwoole\Socket\Config();
        //设置dispatcher 为websocket 模式
        $conf->setType(\EasySwoole\Socket\Config::WEB_SOCKET);
        //设置解析器对象
        $conf->setParser(new WebSocketParser);
        $dispatch = new Dispatcher($conf);

        $register->set(EventRegister::onMessage,function (\swoole_websocket_server $server,\swoole_websocket_frame $frame)use($dispatch){
            $dispatch->dispatch($server,$frame->data,$frame);
        });
        //自定义握手事件
        $websocketEvent = new WebSocketEvent();
        $register->set(EventRegister::onHandShake,function (\swoole_http_request $request,\swoole_http_response $response)use($websocketEvent){
            $websocketEvent->onHandShake($request, $response);
        });
        //注册事件
        //自定义关闭事件
        $register->set(EventRegister::onClose, function (\swoole_server $server, int $fd, int $reactorId) use ($websocketEvent) {
            $websocketEvent->onClose($server, $fd, $reactorId);
        });
        //自定义打开事件
        $register->set(EventRegister::onOpen,function (\swoole_websocket_server $server,\swoole_http_request $request)use($websocketEvent){
            $websocketEvent->onOpen($server,$request);
        });

    }

    public static function onRequest(Request $request, Response $response): bool
    {
        // IP限流
        // $fd = $request->getSwooleRequest()->fd;
        // $ip = ServerManager::getInstance()->getSwooleServer()->getClientInfo($fd)['remote_ip'];
        // if (IpList::getInstance()->access($ip) > 3) {
        //     /**
        //      * 直接强制关闭连接
        //      */
        //     ServerManager::getInstance()->getSwooleServer()->close($fd);
        //     echo '被拦截'.PHP_EOL;
        //     return false;
        // }

        $allow_origin = array(
            'http://192.168.108.131',
            'http://192.168.23.128',
            'http://esadmin.com',
        );
        $origin = $request->getHeader('origin');
        if ($origin !== []){
            $origin = $origin[0];
            //if(in_array($origin, $allow_origin)){
                $response->withHeader('Access-Control-Allow-Origin', '*');
                $response->withHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
                $response->withHeader('Access-Control-Allow-Credentials', 'true');
                $response->withHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization, X-Requested-With, token');
                if ($request->getMethod() === 'OPTIONS') {
                    $response->withStatus(Status::CODE_OK);
                    return false;
                }
            //}
        }
        $response->withHeader('Content-type', 'application/json;charset=utf-8');
        return true;
    }

    public static function afterRequest(Request $request, Response $response): void
    {
        // TODO: Implement afterAction() method.
    }
}